#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <iostream>

MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    qDebug()<<"服务端开始";

    labSocketState = new QLabel("socket 状态：");
    labSocketState->setMinimumWidth(200);
    ui->statusBar->addWidget(labSocketState);

    QString localIPv4 = getLocalIPv4(); // 获取本机 IP 地址
    this->setWindowTitle(this->windowTitle() + "----本机 IP 地址：" + localIPv4);
    ui->comboServer->addItem(localIPv4);

    tcpClient=new QTcpSocket(this);

    //如果 connect 它一个 nullptr 它会调试的时候没反应。
    connect(tcpClient, &QTcpSocket::connected, this, &MainWindow::do_connected);
    connect(tcpClient, &QTcpSocket::disconnected, this, &MainWindow::do_disconnected);
    connect(tcpClient, &QTcpSocket::stateChanged, this, &MainWindow::do_socketStateChanged);
    connect(tcpClient, &QTcpSocket::readyRead, this, &MainWindow::do_socketReadyRead);

    // “连接服务器”按钮
    connect(ui->actConnect, &QAction::triggered, this, [this]() {
        QString addr = ui->comboServer->currentText();
        uint16_t port = ui->spinPort->value();
        tcpClient->connectToHost(addr, port);
    });
    // “断开连接”按钮
    connect(ui->actDisconnect, &QAction::triggered, this, [this]() {
        if (tcpClient->state() == QAbstractSocket::SocketState::ConnectedState)
        {
            tcpClient->disconnectFromHost();
        }
    });
    // “发送消息”按钮
    connect(ui->btnSend, &QPushButton::clicked, this, [this]() {
        QString msg = ui->editMsg->text();
        ui->textEdit->appendPlainText("【发送】 " + msg);
        ui->editMsg->clear();
        msg += '\n';
        QByteArray sendData = msg.toUtf8();
        tcpClient->write(sendData);
    });
    std::cout<<__FILE__<<"  "<<__LINE__<<std::endl;
}

MainWindow::~MainWindow()
{
    if (tcpClient->state() == QAbstractSocket::SocketState::ConnectedState)
    {
        tcpClient->disconnectFromHost();
    }
    delete ui;
}

QString MainWindow::getLocalIPv4()
{
    QString hostName = QHostInfo::localHostName(); // 本机主机名
    QHostInfo hostInfo = QHostInfo::fromName(hostName);
    QString localIPv4 = "";
    QList<QHostAddress> addrList = hostInfo.addresses(); // 本机 IP 地址列表
    if (addrList.isEmpty())
        return localIPv4;
    for (const auto& aHost : addrList)
    {
        if (aHost.protocol() == QAbstractSocket::IPv4Protocol)
        {
            localIPv4 = aHost.toString();
            break;
        }
    }
    return localIPv4;
}

void MainWindow::do_connected()
{
    ui->textEdit->appendPlainText("已经连接到服务器");
    ui->textEdit->appendPlainText("对方地址  " + this->tcpClient->peerAddress().toString());
    ui->textEdit->appendPlainText("对方端口  " + QString::number(tcpClient->peerPort()));
    ui->actConnect->setEnabled(false);
    ui->actDisconnect->setEnabled(true);
}

void MainWindow::do_disconnected()
{
    ui->textEdit->appendPlainText("**已断开与服务器的连接");
    ui->actConnect->setEnabled(true);
    ui->actDisconnect->setEnabled(false);
}

void MainWindow::do_socketStateChanged(QAbstractSocket::SocketState socketState)
{
    qDebug() << "do_socketStateChanged";
    QString state = "";
    switch (socketState)
    {
    case QAbstractSocket::SocketState::UnconnectedState:
        state = "UnconnectedState";
        break;
    case QAbstractSocket::SocketState::HostLookupState:
        state = "HostLookupState";
        break;
    case QAbstractSocket::SocketState::ConnectingState:
        state = "ConnectingState";
        break;
    case QAbstractSocket::SocketState::ConnectedState:
        state = "ConnectedState";
        break;
    case QAbstractSocket::SocketState::BoundState:
        state = "BoundState";
        break;
    case QAbstractSocket::SocketState::ListeningState:
        state = "ListeningState";
        break;
    case QAbstractSocket::SocketState::ClosingState:
        state = "ClosingState";
        break;
    default:
        break;
    }
    labSocketState->setText(state);
}

void MainWindow::do_socketReadyRead()
{
    // // 判断当前 TCP 套接字的接收缓冲区中是否有一整行数据可以读取。
    // while (tcpClient->canReadLine())//必须以换行符结尾 只有在收到完整的一行（以 \n 或 \r\n 结尾）时才会返回数据。
    // {
    //     QString received = tcpClient->readLine();
    //     qDebug()<<"received "<<received;
    //     // 读取缓冲区的行文本
    //     ui->textEdit->appendPlainText("【收到】 " + received);
    // }

    QByteArray data = tcpClient->readAll(); // 读取所有可用数据
    qDebug() << "原始数据  " << data;
    // 如果是文本，可以尝试按行分割
    QStringList lines = QString::fromUtf8(data).split('\n');
    for (const QString& line : lines)
    {
        if (!line.isEmpty())
        {
            ui->textEdit->appendPlainText("【收到】 " + line);
        }
    }
}
